package com.berwin.syncer;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Bundle;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.berwin.adapter.TextAdapter;
import com.berwin.adapter.ViewPagerAdapter;
import com.berwin.entity.SharedText;
import com.berwin.listener.ClipboardChangeListener;
import com.berwin.listener.FileTransferListener;
import com.berwin.listener.SocketEventListener;
import com.berwin.network.Session;
import com.berwin.network.SessionFile;
import com.berwin.services.ClipboardService;
import com.berwin.services.SocketService;
import com.berwin.utility.ClipboardUtility;
import com.berwin.utility.PathUtility;
import com.berwin.utility.PermissionsUtils;
import com.berwin.utility.UserDefault;
import com.berwin.zxing.android.CaptureActivity;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.tabs.TabLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.FileProvider;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager.widget.ViewPager;

import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import java.io.File;

public class MainActivity extends AppCompatActivity implements SocketEventListener, ClipboardChangeListener, FileTransferListener, ConnectDialog.ConnectInfoListener {

    private static final int REQUEST_CODE_SCAN = 0x001;
    private static final int REQUEST_PICK_FILE_CODE = 0x002;

    private TabLayout tabLayout;
    private ViewPager viewPager;
    private ViewPagerAdapter viewPagerAdapter;

    private ProgressDialog progressDialog;

    private SocketService socketService;
    private ClipboardService clipboardService;

    private boolean isConnectServer = false;

    private ServiceConnection socketConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            SocketService.CustomBinder binder = (SocketService.CustomBinder) service;
            binder.setListener(MainActivity.this, MainActivity.this);
            MainActivity.this.socketService = binder.getService();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };
    private ServiceConnection clipboardConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            ClipboardService.CustomBinder binder = (ClipboardService.CustomBinder) service;
            binder.setListener(MainActivity.this);
            MainActivity.this.clipboardService = binder.getService();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };


    public static final int HANDLER_SHOW_PROGRESS_DIALOG = 100;
    public static final int HANDLER_UPDATE_PROGRESS_DIALOG = 101;
    public static final int HANDLER_CLOSE_PROGRESS_DIALOG = 102;
    @SuppressLint("HandlerLeak")
    private Handler updateListHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == Session.MSG_TYPE_SYNC_TEXT) { // 刷新文本列表
                SharedText sharedText = (SharedText) msg.obj;
                TextAdapter adapter = MainActivity.this.viewPagerAdapter.getTextsFragment().getAdapter();
                adapter.addItem(0, sharedText);
                adapter.notifyDataSetChanged();
                ClipboardService.lastClipboardContent = sharedText.getContent();
                ClipboardUtility.copy(MainActivity.this, sharedText.getContent());
            } else if (msg.what == Session.MSG_TYPE_CONNECT) { // 连接，更新标题
                Toolbar toolbar = findViewById(R.id.toolbar);
                toolbar.setSubtitle("已连接");
            } else if (msg.what == Session.MSG_TYPE_DISCONNECT) { // 断开连接，更新标题
                Toolbar toolbar = findViewById(R.id.toolbar);
                toolbar.setSubtitle("未连接");
                unbindService(socketConnection);
            } else if (msg.what == Session.MSG_TYPE_SYNC_TEXTS) { // 同步所有缓存消息
                TextAdapter adapter = MainActivity.this.viewPagerAdapter.getTextsFragment().getAdapter();
                adapter.removeAll();
                JSONArray texts = (JSONArray) msg.obj;
                for (int i = texts.size() - 1; i >= 0; i--) {
                    JSONObject text = texts.getJSONObject(i);
                    SharedText sharedText = SharedText.parseFromJSONObject(text);
                    adapter.addItem(sharedText);
                }
                adapter.notifyDataSetChanged();
                if (texts.size() <= 0)
                    return;
                SharedText sharedText = SharedText.parseFromJSONObject(texts.getJSONObject(0));
                ClipboardService.lastClipboardContent = sharedText.getContent();
                ClipboardUtility.copy(MainActivity.this, sharedText.getContent());
            } else if (msg.what == HANDLER_SHOW_PROGRESS_DIALOG) {
                MainActivity.this.showProgressDialog(msg.getData().getString("title"), msg.getData().getString("message"));
            } else if (msg.what == HANDLER_UPDATE_PROGRESS_DIALOG) {
                MainActivity.this.updateProgressDialog((int) msg.obj);
            } else if (msg.what == HANDLER_CLOSE_PROGRESS_DIALOG) {
                MainActivity.this.closeProgressDialog();
                if ((int) msg.obj == 0) {
                    String path = msg.getData().getString("path");
                    // 成功
                    MainActivity.this.confirmOpenDownloadDirectory(path);
                } else {
                    // 失败
                    Toast.makeText(MainActivity.this, "文件传输失败", Toast.LENGTH_LONG).show();
                }
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        UserDefault.getInstance().init(this);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        toolbar.setSubtitle("未连接");

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                MainActivity.this.viewPagerAdapter.getTextsFragment().getAdapter().removeAll();
                MainActivity.this.viewPagerAdapter.getTextsFragment().getAdapter().notifyDataSetChanged();
            }
        });
        this.initPageViewer();

        Intent intent = new Intent(this, ClipboardService.class);
        bindService(intent, clipboardConnection, Context.BIND_AUTO_CREATE);

        //两个日历权限和一个数据读写权限
        String[] permissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE};
//        PermissionsUtils.showSystemSetting = false;//是否支持显示系统设置权限设置窗口跳转
        //这里的this不是上下文，是Activity对象！
        PermissionsUtils.IPermissionsResult permissionsResult = new PermissionsUtils.IPermissionsResult() {
            @Override
            public void passPermissons() {

            }

            @Override
            public void forbitPermissons() {
                Toast.makeText(MainActivity.this, "请授予权限", Toast.LENGTH_LONG).show();
            }
        };
        PermissionsUtils.getInstance().chekPermissions(this, permissions, permissionsResult);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        MenuItem menuItem = menu.findItem(R.id.action_upload);
        menuItem.setEnabled(this.isConnectServer);
        MenuItem connectItem = menu.findItem(R.id.action_connect);
        connectItem.setEnabled(!this.isConnectServer);
        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PermissionsUtils.getInstance().onRequestPermissionsResult(this, requestCode, permissions, grantResults);
    }

    private void initPageViewer() {
        this.tabLayout = findViewById(R.id.tabLayout);
        this.viewPager = findViewById(R.id.viewPager);
        this.viewPagerAdapter = new ViewPagerAdapter(this.getSupportFragmentManager(), this);
        this.viewPager.setAdapter(this.viewPagerAdapter);
        this.tabLayout.setupWithViewPager(this.viewPager);
    }

    public ViewPagerAdapter getViewPagerAdapter() {
        return this.viewPagerAdapter;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_connect) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            ConnectDialog connectDialog = new ConnectDialog();
            connectDialog.setCancelable(false);
            connectDialog.show(fragmentManager, "login_tip_dialog");
//            Intent intent = new Intent(this, SocketService.class);
//            intent.putExtra("host", "192.168.1.106");
//            intent.putExtra("port", 11098);
//            intent.putExtra("port_file", 11099);
//            bindService(intent, socketConnection, Context.BIND_AUTO_CREATE);
            return true;
        } else if (id == R.id.action_upload) {
            this.pickFile();
        } else if (id == R.id.action_delete) {
            this.deleteDownloadDirectory();
        }
//        else if (id == R.id.action_open) {
//            this.openDownloadDirectory();
//        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onConnectInfoChanged(boolean useScanner, String host, int portText, int portFile) {
        if (useScanner) {
            Intent intent = new Intent(this, CaptureActivity.class);
            this.startActivityForResult(intent, REQUEST_CODE_SCAN);
        } else {
            Intent intent = new Intent(this, SocketService.class);
            intent.putExtra("host", host);
            intent.putExtra("port", portText);
            intent.putExtra("port_file", portFile);
            bindService(intent, socketConnection, Context.BIND_AUTO_CREATE);
        }

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK
                && requestCode == REQUEST_CODE_SCAN) {
            String datastr = data.getStringExtra("codedContent");
            String datas[] = datastr.split("-");
            if (datas.length < 2) {
                this.showTip("扫码数据有误:" + datastr);
                return;
            }
            String host = datas[0];
            int port = Integer.parseInt(datas[1]);
            int port_file = Integer.parseInt(datas[2]);
            Intent intent = new Intent(this, SocketService.class);
            intent.putExtra("host", host);
            intent.putExtra("port", port);
            intent.putExtra("port_file", port_file);
            bindService(intent, socketConnection, Context.BIND_AUTO_CREATE);
        } else if (resultCode == RESULT_OK
                && requestCode == REQUEST_PICK_FILE_CODE) {
            Uri uri = data.getData(); // 获取用户选择文件的URI
            try {
//                String path = Utility.getRealPathFromUri(this, uri);
                String path = PathUtility.path2URL(this, uri);
                if (path == null || "".equals(path)) {
                    Log.w("PICK_FILE", "path is null or empty");
                    return;
                }
                Log.i("PICK_FILE", path);
                this.socketService.sendFile(path);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    public void showTip(String text) {
        Log.i("MainActivity", text);
        Snackbar.make(findViewById(R.id.fab), text, Snackbar.LENGTH_LONG)
                .setAction("Action", null).show();
    }

    public void showProgressDialog(String title, String fileName) {
        progressDialog = new ProgressDialog(this);
        progressDialog.setTitle(title);
        progressDialog.setMessage(fileName);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setCancelable(false);
        progressDialog.setCanceledOnTouchOutside(false);
        progressDialog.setIndeterminate(false);
        progressDialog.show();
    }

    public void updateProgressDialog(int percent) {
        if (progressDialog != null)
            progressDialog.setProgress(percent);
    }

    public void closeProgressDialog() {
        if (progressDialog != null) {
            progressDialog.cancel();
            progressDialog = null;
        }
    }

    public void deleteDownloadDirectory() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("删除目录?");
        builder.setMessage("确认清除下载目录");
        builder.setPositiveButton("删除", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                File directory = new File(SocketService.DOWNLOAD_DIR);
                if (directory.exists())
                    MainActivity.this.deleteDirWihtFile(directory);

            }
        });
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });
        builder.show();
    }

    public void deleteDirWihtFile(File dir) {
        if (dir == null || !dir.exists() || !dir.isDirectory())
            return;
        for (File file : dir.listFiles()) {
            if (file.isFile())
                file.delete(); // 删除所有文件
            else if (file.isDirectory())
                deleteDirWihtFile(file); // 递规的方式删除文件夹
        }
        dir.delete();// 删除目录本身
    }

    public void openDownloadDirectory() {
        File directory = new File(SocketService.DOWNLOAD_DIR + File.separator);
        if (!directory.exists())
            directory.mkdirs();
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//        intent.addCategory(Intent.CATEGORY_OPENABLE);
//        intent.setData(FileProvider.getUriForFile(this, getPackageName() + ".FileProvider", directory));
        Log.i("MainActivity", "打开路径:" + directory.getAbsolutePath());
        intent.setDataAndType(FileProvider.getUriForFile(this, getPackageName() + ".FileProvider", directory), "*/*");
//        intent.setDataAndType(Uri.parse(directory.getAbsolutePath()), DocumentsContract.Document.MIME_TYPE_DIR);
        try {
            startActivity(intent);
//            startActivity(Intent.createChooser(intent,"选择浏览工具"));
        } catch (ActivityNotFoundException e) {
            Toast.makeText(this, "没有安装资源管理软件", Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }
    }

    public void confirmOpenDownloadDirectory(String path) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("文件传输完成");
        builder.setMessage("目录:" + path);
        builder.setPositiveButton("知道了", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
//                MainActivity.this.openDownloadDirectory();
            }
        });
//        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
//            @Override
//            public void onClick(DialogInterface dialog, int which) {
//
//            }
//        });
        builder.show();
    }

    @Override
    public void onConnect(Session session) {
        this.showTip("连接成功");
        this.isConnectServer = true;
        Message message = new Message();
        message.what = Session.MSG_TYPE_CONNECT;
        updateListHandler.sendMessage(message);
    }

    @Override
    public void onMessage(Session session, JSONObject data) {
        if (data == null)
            return;
        Log.i("MainActivity", "收到消息:" + data.toJSONString());
        // 添加到列表中
        int type = data.getInteger("type");
        if (type == Session.MSG_TYPE_SYNC_TEXTS) { // 同步所有缓存消息
            JSONArray texts = data.getJSONArray("texts");
            Message message = new Message();
            message.what = Session.MSG_TYPE_SYNC_TEXTS;
            message.obj = texts;
            this.updateListHandler.sendMessage(message);
        } else if (type == Session.MSG_TYPE_SYNC_TEXT) { // 新增一条复制消息
            Message message = new Message();
            message.what = Session.MSG_TYPE_SYNC_TEXT;
            message.obj = SharedText.parseFromJSONObject(data);
            this.updateListHandler.sendMessage(message);
        }
    }

    @Override
    public void onDisconnect(Session session) {
        this.showTip("断开成功");
        Message message = new Message();
        message.what = Session.MSG_TYPE_DISCONNECT;
        updateListHandler.sendMessage(message);
        this.isConnectServer = false;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (socketConnection != null)
            unbindService(socketConnection);
        if (clipboardConnection != null)
            unbindService(clipboardConnection);
    }

    public String getLastClipboardContent() {
        return ClipboardService.lastClipboardContent;
    }

    public void setLastClipboardContent(String lastClipboardContent) {
        ClipboardService.lastClipboardContent = lastClipboardContent;
    }

    @Override
    public void onClipboardChanged(String text) {
        JSONObject obj = new JSONObject();
        obj.put("type", Session.MSG_TYPE_SYNC_TEXT);
        obj.put("sender", this.getName());
        obj.put("content", text);
        this.socketService.send(obj.toJSONString());
    }

    public String getName() {
        String brand = android.os.Build.BRAND;
        String model = android.os.Build.MODEL;
        return brand + " " + model;
    }

    // 打开系统的文件选择器
    public void pickFile() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false);//打开多个文件
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        this.startActivityForResult(Intent.createChooser(intent, "选择上传文件"), REQUEST_PICK_FILE_CODE);
    }

    @Override
    public void onStart(SessionFile task, String path, String fileName) {
        Message message = new Message();
        message.what = HANDLER_SHOW_PROGRESS_DIALOG;
        Bundle bundle = new Bundle();
        bundle.putString("title", "文件传输中...");
        bundle.putString("message", fileName);
        message.setData(bundle);
        updateListHandler.sendMessage(message);
    }

    @Override
    public void onProgress(SessionFile task, int percent) {
        Message message = new Message();
        message.what = HANDLER_UPDATE_PROGRESS_DIALOG;
        message.obj = percent;
        updateListHandler.sendMessage(message);
    }

    @Override
    public void onFinished(SessionFile task, String path, String fileName) {
        Log.i("MainActivity", "文件传输完成");
        Message message = new Message();
        message.what = HANDLER_CLOSE_PROGRESS_DIALOG;
        message.obj = 0;
        Bundle bundle = new Bundle();
        bundle.putString("path", path + File.separator + fileName);
        message.setData(bundle);
        updateListHandler.sendMessage(message);
    }

    @Override
    public void onError(SessionFile task, String desc) {
        Log.i("MainActivity", "文件传输出错:" + desc);
        Message message = new Message();
        message.what = HANDLER_CLOSE_PROGRESS_DIALOG;
        message.obj = 1;
        updateListHandler.sendMessage(message);
    }
}
